package cn.dzh.service.impl;

import cn.dzh.dal.mapper.CommodityBaseMapper;
import cn.dzh.dal.mapper.CommodityDraftMapper;
import cn.dzh.dal.mapper.CommodityOperateMapper;
import cn.dzh.model.bean.CommodityBase;
import cn.dzh.model.bean.CommodityDraft;
import cn.dzh.model.bean.CommodityOperate;
import cn.dzh.model.dto.GoodsOperateDTO;
import cn.dzh.model.dto.Result;
import cn.dzh.service.CommodityOperateService;
import cn.dzh.utils.RedisUtils;
import cn.hutool.core.bean.BeanUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * @version V1.0
 * @description:
 * @author: dzd
 * @date: 2023/10/24
 */
@Service
public class CommodityOperateServiceImpl implements CommodityOperateService {
    @Resource
    private CommodityOperateMapper commodityOperateMapper ;

    @Resource
    private CommodityDraftMapper commodityDraftMapper;

    @Resource
    private CommodityBaseMapper commodityBaseMapper;

    @Resource
    private RedisUtils redisUtils;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> goodsOnline(GoodsOperateDTO goodsOperateDTO) {
        CommodityBase commodityBase = null;
        try {
            commodityBase = getCommodityBaseFromCacheOrDb(goodsOperateDTO.getGoodsId());
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Error retrieving commodity data from cache or database.", e);
        }
        //判断商品是否审核通过,如果未审核通过则不能上线
        if (commodityBase == null){
            return new Result<>(false, "商品不存在");
        } else if (!"审核通过".equals(commodityBase.getAuditResult())){
            return new Result<>(false, "商品未审核通过");
        } else if ("已上线".equals(commodityBase.getOnlineStatus())){
            return new Result<>(false, "商品已上线,请勿重复上线");
        }
        insertAndUpdateOnline("上线", goodsOperateDTO,"已上线", commodityBase);
        // 删除缓存
        redisUtils.delete("commodityBase:" + goodsOperateDTO.getGoodsId());
        return new Result<>(true, "商品上线成功");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> goodsOffline(GoodsOperateDTO goodsOperateDTO) {
        CommodityBase commodityBase = null;
        try {
            commodityBase = getCommodityBaseFromCacheOrDb(goodsOperateDTO.getGoodsId());
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Error retrieving commodity data from cache or database.", e);
        }

        //判断商品是否上线,如果未上线则不能下线
        if (commodityBase == null){
            return new Result<>(false, "商品不存在");
        } else if (!"已上线".equals(commodityBase.getOnlineStatus())){
            return new Result<>(false, "商品未上线,请先上线");
        }

        insertAndUpdateOnline("下线", goodsOperateDTO,"已下线", commodityBase);

        // 删除缓存
        redisUtils.delete("commodityBase:" + goodsOperateDTO.getGoodsId());

        return new Result<>(true, "商品下线成功");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result pushAudit(GoodsOperateDTO goodsOperateDTO) {
        CommodityBase commodityBase = null;
        try {
            commodityBase = getCommodityBaseFromCacheOrDb(goodsOperateDTO.getGoodsId());
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Error retrieving commodity data from cache or database.", e);
        }

        if (commodityBase == null){
            return new Result<>(false, "商品不存在，或请先添加商品");
        }else if ("未审核".equals(commodityBase.getAuditResult())){
            return new Result<>(false, "商品已提交审核,请勿重复提交");
        }else if ("已上线".equals(commodityBase.getOnlineStatus())){
            return new Result<>(false, "商品已上线,请先下线");
        }

        insertAndUpdateAudit("提交审核", goodsOperateDTO,"未审核", commodityBase);

        // 删除缓存
        redisUtils.delete("commodityBase:" + goodsOperateDTO.getGoodsId());

        return new Result<>(true, "商品推送审核成功");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result approv(GoodsOperateDTO goodsOperateDTO) {
        CommodityBase commodityBase = null;
        try {
            commodityBase = getCommodityBaseFromCacheOrDb(goodsOperateDTO.getGoodsId());
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Error retrieving commodity data from cache or database.", e);
        }

        if (commodityBase == null){
            return new Result<>(false, "商品不存在，或请先添加商品");
        }else if (!"未审核".equals(commodityBase.getAuditResult())){
            return new Result<>(false, "商品已审核,请勿重复审核");
        }

        insertAndUpdateAudit("审核通过", goodsOperateDTO,"审核通过", commodityBase);

        // 删除缓存
        redisUtils.delete("commodityBase:" + goodsOperateDTO.getGoodsId());

        return new Result<>(true, "商品审核成功");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result reject(GoodsOperateDTO goodsOperateDTO) {
        CommodityBase commodityBase = null;
        try {
            commodityBase = getCommodityBaseFromCacheOrDb(goodsOperateDTO.getGoodsId());
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Error retrieving commodity data from cache or database.", e);
        }

        if (commodityBase == null){
            return new Result<>(false, "商品不存在，或请先添加商品");
        }else if (!"未审核".equals(commodityBase.getAuditResult())){
            return new Result<>(false, "商品已审核,请勿重复审核");
        }

        insertAndUpdateAudit("审核驳回", goodsOperateDTO,"审核驳回", commodityBase);

        // 删除缓存
        redisUtils.delete("commodityBase:" + goodsOperateDTO.getGoodsId());

        return new Result<>(true, "商品审核驳回成功");
    }


    /**
     * 插入商品操作表和更新商品基本的审核状态
     * @param operate 操作
     * @param goodsOperateDTO 商品操作参数
     * @param auditResult 审核结果
     * @param commodityBase 商品基本信息
     */
    private void insertAndUpdateAudit(String operate, GoodsOperateDTO goodsOperateDTO,String auditResult, CommodityBase commodityBase){
        //插入商品操作表
        CommodityOperate commodityOperate = getCommodityOperate(operate, goodsOperateDTO);
        commodityOperateMapper.insertSelective(commodityOperate);
        //更新商品基本表
        commodityBase.setAuditResult(auditResult);
        commodityBaseMapper.updateByPrimaryKeySelective(commodityBase);
    }

    /**
     * 插入商品操作表和更新商品基本的上线状态
     * @param operate   操作
     * @param goodsOperateDTO 商品操作参数
     * @param onlineStatus 上线状态
     * @param commodityBase 商品基本信息
     */
    private void insertAndUpdateOnline(String operate, GoodsOperateDTO goodsOperateDTO,String onlineStatus, CommodityBase commodityBase){
        //插入商品操作表
        CommodityOperate commodityOperate = getCommodityOperate(operate, goodsOperateDTO);
        commodityOperateMapper.insertSelective(commodityOperate);
        //更新商品基本表
        commodityBase.setOnlineStatus(onlineStatus);
        commodityBaseMapper.updateByPrimaryKeySelective(commodityBase);
    }

    /**
     * 封装商品操作表
     * @param status 操作状态
     * @param goodsOperateDTO 商品操作参数
     * @return CommodityOperate
     */
    private CommodityOperate getCommodityOperate(String status,GoodsOperateDTO goodsOperateDTO){
        goodsOperateDTO.setOperateStatus(status);
        CommodityOperate commodityOperate = new CommodityOperate();
        BeanUtil.copyProperties(goodsOperateDTO,commodityOperate);
        return commodityOperate;
    }

    /**
     * 从Redis中获取商品基本信息
     * @param goodsId 商品id
     * @return CommodityBase
     * @throws JsonProcessingException
     */
    private CommodityBase getCommodityBaseFromCacheOrDb(Integer goodsId) throws JsonProcessingException {
        // 构建Redis的key
        String key = "commodityBase:" + goodsId;

        CommodityBase commodityBase = redisUtils.getObject(key, CommodityBase.class);
        if (commodityBase == null) {
            commodityBase = commodityBaseMapper.selectByPrimaryKey(goodsId);
            if (commodityBase != null) {
                redisUtils.setObject(key, commodityBase);
            }
        }
        return commodityBase;
    }

    /**
     * 删除商品基本信息缓存
     * @param goodsId 商品id
     */
    private void deleteCommodityBaseCache(Integer goodsId) {
        String key = "commodityBase:" + goodsId;
        redisUtils.delete(key);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addToBase(Integer id) {
        CommodityDraft commodityDraft = commodityDraftMapper.selectByPrimaryKey(id);
        if ("审核通过".equals(commodityDraft.getAuditStatus())) {
            int i = commodityOperateMapper.addToBaseTab(commodityDraft);
            int i1 = commodityOperateMapper.addToServiceTerm(commodityDraft);
            int i2 = commodityOperateMapper.addToExchangePrice(commodityDraft);
            if (i > 0 && i1 > 0 && i2 > 0) {
                return true;
            } else {
                throw new RuntimeException();
            }
        } else {
            return false;
        }
    }


}
